<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <style>
        textarea{
            overflow:auto;
            height:99%;
            width:100%;
            background-color:white;
            border: 1px solid grey;
            -moz-border-radius: 10px;
            padding: 10px;
        }

        select,
        input{
            padding: 10px;
            background-color:white;
            border: 1px solid grey;
            color:black;
            -moz-border-radius: 10px;
        }

        th{
            height:1;
        }

        table{
            height:80%;
            border: 1px solid blue;
        }

        td{
            width:50%;
        }

        .source{
            background-color: #FFE;
        }

        .result{
            background-color: #EFF;
        }

        .status{
            border: 1px solid orange;
            -moz-border-radius: 10px;
            margin: 10px 0;
            padding: 5px;
        }

        .title {
            font-size:1.5em;
        }

        .button{
            background-color:#FFC;
            font-weight:bolder;
        }
    </style>

    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <!--
    <script type="text/javascript" src="http://www.prototypejs.org/assets/2008/9/29/prototype-1.6.0.3.js"></script>
    -->
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript">

    google.load("language", "1");

    /**
     * source content object, living in global space so it can be accessed by callbacks
     */
    var sourceLines; // type: Array

    /**
     * a explict point for going through yaml
     */
    var currentLineNumber;

    /**
     * the text field for result output
     */
    var resultField;

    /**
     * the language code of source content
     */
    var sourceLanguageCode = null;

    /**
     * init mark the system is ready
     */
    google.setOnLoadCallback(
        function(){
            updateStatus("Ready".bold());
            resultField = $("result_field");
            resultField.value = "";
            // $("source_content").value = "";

            // populate target languages
            var values = Object.values(google.language.Languages);
            var keys = Object.keys(google.language.Languages);
            for(var i = 0; i<keys.length; i++)
            {
                values[i] = '<option value="'+values[i]+'">'+keys[i]+'('+values[i]+')'+'</option>'
            }

            $("language_select").update(values.join(' '));
        }
    );


    /**
     * update the sataus message
     *
     * @param msg [String] the status message to display
     */
    function updateStatus(msg)
    {
        $("status_node").update(msg);
    }

    /**
     * start the translation
     */
    function doTranslate()
    {
        // get the source content
        var source_content = $("source_content").value.strip();

        if(source_content == "")
        {
            reportFailure("missing source content");
            return;
        }

        sourceLines = source_content.split('\n');
        currentLineNumber= 0;
        resultField.value = "";

        detectLanguage();
        
        return false;
    }

    /**
     * translate the yaml line by line
     */
    function translateLine()
    {
        // reach end?
        if(currentLineNumber >= sourceLines.length)
        {
            updateStatus("Translation completed".bold());
            return
        }

        // get the current line content
        var currentLine = sourceLines[currentLineNumber++];

        var lineObj = extractContent(currentLine);

        if(!lineObj)
        {
            addTranslatedResult(currentLine);
            translateLine();
            return;
        }

        addTranslatedResult(lineObj.leadingSpaces+lineObj.key+':"');
        gTranslate(lineObj.content);
    }

    /**
     * detect the language code of the source content
     */
    function detectLanguage()
    {
        for(var i=0; i<sourceLines.length; i++)
        {
            var lineObj = extractContent(sourceLines[i]);
            if(!lineObj)
            {
                continue;
            }
            else
            {
                google.language.detect(lineObj.content, 
                    function(result)
                    {
                        if (result.error)
                        {
                            updateStatus("Translation failed, please try again".bold());
                            reportFailure("can not detect the language of the source YMAL");
                        }
                        else
                        {
                            sourceLanguageCode = result.language;
                            updateStatus(("Translating ("+sourceLanguageCode+">"+
                                $F("language_select")+") ...").bold().fontcolor("green").blink());
                            translateLine();
                        }
                    }
                );
                break;
            }

        }

        return false;
        sourceLanguageCode
    }

    /**
     * extract content string from a line of yaml code
     *
     * @param line [String] a line of yaml code
     *
     * @return [{leadingSpaces:String, key:String, content:String}] extracted content string.
     *         If not content string can be extracted, then return null
     */
    function extractContent(line)
    {
        // is this a valid key:value line
        if(line.indexOf(':') == -1)
        {
            return null;
        }

        // is this a valid key:value line, again
        var strippedLine = line.strip();
        if(strippedLine.lastIndexOf(':') == strippedLine.length -1)
        {
            return null
        }

        var lineObj = {}

        // translate this line
        line.scan(/\s+(.*?)\:\s+\"(.*?)\"/,  function(match)
            {
                // get leading spaces
                var firstHalf = match[0].split(':')[0];
                var leadingSpaces = ' '.times(firstHalf.lastIndexOf(' ') + 1);
              
                lineObj = {
                    leadingSpaces:' '.times(firstHalf.lastIndexOf(' ') + 1),
                    key:match[1],
                    content:match[2]
                }
            }
        )

        return lineObj;
    }

    /**
     * add translated line into the result field
     *
     * @param content [String]
     */
    function addTranslatedResult(content)
    {
        resultField.value += "\n"+ content;
    }

    function padTranslatedResult(content)
    {
        content = content.gsub(/\<span\s+class\=\"notranslate\"\>\{\{(.*?)\}\}\<\/span\>/,
            '{{#{1}}}');

        resultField.value += content + '"';

        // scrolling textarea causes blinking in firefox :(
        // resultField.scrollTop = resultField.scrollHeight;
        translateLine();
    }


    /**
     * report failure message into the output field
     *
     * @param msg[String] failure message
     */
    function reportFailure(msg)
    {
        resultField.value = "ERROR!!!\n"+msg;
    }

    /**
     * wrap the google translator
     */
    function gTranslate(text)
    {

        text = text.gsub(/\{\{(.*?)\}\}/, '<span class="notranslate">{{#{1}}}</span>')

        if (!sourceLanguageCode || !$F("language_select"))
        {
            updateStatus("Translation halted.".bold());
            reportFailure("missing source language code or target language code.");
            return;
        }

        google.language.translate(text, sourceLanguageCode, $F("language_select"),  function(result)
        {
            var translated = document.getElementById("translation");
            if (result.translation) {
                padTranslatedResult(result.translation);
            }
            else
            {
                padTranslatedResult("ERROR!"+ result.error.message +"(code:"+result.error.code+")");
            }
        });
    }


    </script>
  </head>
  <body>
      <h1 class="title">
          Rails localisation YAML translator
      </h1>
    <div class="status">
        Status:
        <span id="status_node">Waiting for Google translate API...</span>
    </div>

<form action="js_translate">
<dir>
    Target language:
    <select name="language_select" id="language_select"></select>
    <input type="button" value="Translate" name="translate_btn" class="button" onclick="doTranslate()"/>
    
</dir>
<table border="0" cellspacing="0" cellpadding="10" width="100%">
    <thead>
        <tr>
            <th class="source">Source YAML Content:</th>
            <th class="result">Translation:</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td class="source">
                 <textarea id="source_content" name="source_content"  wrap="off"></textarea>
            </td>
            <td class="result">
		<textarea id="result_field" name="source_content"  wrap="off"></textarea>

            </td>
        </tr>
    </tbody>
</table>
</form>

  </body>
</html>
